package cn.rengy.web.framework.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.pam.AbstractAuthenticationStrategy;
import org.apache.shiro.realm.Realm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.rengy.tool.core.util.ExceptionPrintUtils;
/**
 *  自定义实现AuthenticationStrategy
 *  默认实现都无法抛出异常
 *  只是在AllSuccessfulStrategy基础删去掉了beforeAttempt的校验
 * @author rengy
 *
 */
public class OnlyOneAuthenticationStrategy extends AbstractAuthenticationStrategy {
	private static Logger logger = LoggerFactory.getLogger(OnlyOneAuthenticationStrategy.class);
	
	
	/**
	 *  有一个Realm验证失败就抛出异常
	 */
	public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo info, AuthenticationInfo aggregate, Throwable t)
            throws AuthenticationException {
        if (t != null) {
            if (t instanceof AuthenticationException) {
                //propagate:
                throw ((AuthenticationException) t);
            } else {
            	logger.error(ExceptionPrintUtils.getTrace(t));
                String msg = "认证时发生未知错误";
                throw new AuthenticationException(msg, t);
            }
        }
        if (info == null) {
            String msg = "认证信息获取失败";
            throw new UnknownAccountException(msg);
        }


        // If non-null account is returned, then the realm was able to authenticate the
        // user - so merge the account with any accumulated before:
        merge(info, aggregate);

        return aggregate;
    }
}
